#include <iostream>
#include <stdio.h>
#include <string.h>

#pragma pack (2)

using namespace std;

typedef struct BMFH
{
	unsigned short	bfType;
	unsigned int	bfSize;
	unsigned short	bfReserved1;
	unsigned short	bfReserved2;
	unsigned int	bfOffBits;
}bmfh;

typedef struct BMIH
{
	unsigned int	biSize;
	int				biWidth;
	int				biHeight;
	unsigned short	biPlanes;
	unsigned short	biBitCount;
	unsigned int	biCompression;
	unsigned int	biSizeImage;
	unsigned int	biXPelsPerMeter;
	unsigned int	biYPelsPerMeter;
	unsigned int	biClrUsed;
	unsigned int	biClrImportant;
}bmih;

typedef struct RGBQUAD
{
	char	rgbBlue;
	char	rgbGreen;
	char	rgbRed;
	char	rgbReserved;
}rgbquad;

typedef struct BITMAPINFO
{
	bmih 	bmiHeader;
	rgbquad	bmiColors[1];
}bmi;

int main(int argc, char **argv)
{
	//cout << sizeof(bmfh) << endl;
	FILE *fp = NULL;
	bmfh bmHeader;
	bmih infoHeader;

	fp = fopen(argv[1], "rb");
	fread(&bmHeader, sizeof bmHeader, 1, fp);
	fread(&infoHeader, sizeof infoHeader, 1, fp);
	printf("Width:%u\n", infoHeader.biWidth);
	printf("Height:%d\n", infoHeader.biHeight);
	printf("BitCount:%u\n", infoHeader.biBitCount);
	printf("Compression:%u\n", infoHeader.biCompression);
	printf("SizeImage:%u\n", infoHeader.biSizeImage);
	printf("DataOffBits:0x%x\n", bmHeader.bfOffBits);
	char bmData[4096];
	//fseek(fp, sizeof(bmfh) + sizeof(bmih), SEEK_SET);
	fseek(fp, bmHeader.bfOffBits, SEEK_SET);
	memset(bmData, 0xff, sizeof bmData);
	int len = fread(bmData, 1, sizeof bmData, fp);

	printf("len:%d\n", len);
	{
		for (int i = 0; i < len; i++) {
			printf("%hhx", bmData[i]);
		}
	}
	printf("\n");
	int realWidth = (((infoHeader.biWidth + 31) >> 5) << 2) * 8;
	for (int i = infoHeader.biHeight - 1; i >= 0; i--) {
		for (int j = 0; j < realWidth; j++) {
			int bit = realWidth * i + j;
			if (bmData[bit / 8] & (0x80 >> (bit % 8))) {
				printf(" ");
			}
			else {
				if (j >= infoHeader.biWidth) {
					printf(" ");
				}
				else {
					printf("o");
				}
			}
		}
		printf("\n");
	}
	return 0;
}
